package ferp.android.social.fb;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import com.facebook.*;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphUser;
import ferp.android.BuildConfig;
import ferp.android.R;
import ferp.android.dialogs.ShareDialog;
import ferp.android.managers.ProfileManager;
import ferp.android.social.Connector;
import ferp.android.social.Post;
import ferp.core.log.Log;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.LinkedList;
import java.util.List;

/**
 * User: olegs
 * Date: 5/19/13 1:48 PM
 */

//todo: Use UiLifecycleHelper to handle sessions state properly!

public class FbConnector extends Connector
{
  @Override
  public int getRequestCode()
  {
    return RequestCode.FB;
  }

  @Override
  public boolean isLoggedIn(Activity owner)
  {
    Session s = Session.openActiveSessionFromCache(owner);

    return s != null && s.isOpened();
  }

  @Override
  public void onActivityResult(Activity owner, int result, Intent intent)
  {
    Session s = Session.getActiveSession();

    if (s != null)
      s.onActivityResult(owner, Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE, result, intent);

    // even if Fb connector is logged in this callback is called
    if (loginListener != null)
      loginListener.onLoginFinished(getRequestCode(), s != null && result == Activity.RESULT_OK);
  }

  @Override
  public void post(final PostListener postListener, final Activity owner, Post post)
  {
    // get active session
    Session session = Session.getActiveSession();

    // ask for permissions
    session.requestNewPublishPermissions(new Session.NewPermissionsRequest(owner, permissions));

    // prepare parameters
    Bundle params = new Bundle();
    params.putString("message", post.getText(null));
    params.putString("link", Post.link(ProfileManager.instance(owner).getCurrentProfile().settings.locale));
    params.putString("picture", "http://lh3.ggpht.com/NNicxXKelOYdgwfZJbz4K8qtc0_yq851dpjcthx2M1LXB5bc39A6vFSZHd3n0uiaKa41d4zBV0VFsHw5kx8TWDE");

    //params.putString("caption", "The custom caption");
    //params.putString("name", "Preferans game on Google Play");
    //params.putString("description", post.message);
    //params.putString("picture", "https://lh4.ggpht.com/xJtmj_RGCrUk8GknrOXFJRb8cxycu61n1ZJGLAZHptvD0HbImA5gv-6TVmuFKALgQQ=w78-h78");

    if (BuildConfig.DEBUG)
    {
      try
      {
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("value", "SELF");
        params.putString("privacy", jsonObject.toString());
      }
      catch (JSONException e)
      {
        Log.error(TAG, e);
      }
    }

    // post
    Request.Callback callback = new Request.Callback()
    {
      public void onCompleted(Response response)
      {
        GraphObject go = response.getGraphObject();

        if (go == null)
        {
          Log.debug(TAG, "Publish failed - unable to retrieve graph object (" + response + ")");
          postListener.onPostCompleted(FbConnector.this, new PostError(-1, response.toString()));
        }
        else
        {
          JSONObject graphResponse = go.getInnerJSONObject();

          try
          {
            String postID = graphResponse.getString("id");
            FacebookRequestError error = response.getError();

            if (error == null)
            {
              Log.debug(TAG, "Publish succeeded, postID: " + postID);
              postListener.onPostCompleted(FbConnector.this, null);
            }
            else
            {
              Log.debug(TAG, "Publish failed " + error);
              postListener.onPostCompleted(FbConnector.this, new PostError(error.getErrorCode(), error.getErrorMessage()));
            }
          }
          catch (JSONException e)
          {
            Log.error(TAG, e);
            postListener.onPostCompleted(FbConnector.this, new PostError(-2, e.getMessage()));
          }
        }
      }
    };

    // create and send request
    Request request = new Request(session, "me/feed", params, HttpMethod.POST, callback);
    RequestAsyncTask task = new RequestAsyncTask(request);

    task.execute();
  }

  @Override
  public void logout(Activity owner)
  {
    Session s = Session.getActiveSession();

    if (s != null)
      s.closeAndClearTokenInformation();
  }

  @Override
  public ImageView getLogoutIcon(ShareDialog dialog)
  {
    return (ImageView)(dialog.findViewById(R.id.social_frame_layout_fb).findViewById(R.id.dlg_share_logout));
  }

  @Override
  public ImageView getProgressIcon(ShareDialog dialog)
  {
    return (ImageView)(dialog.findViewById(R.id.social_frame_layout_fb).findViewById(R.id.dlg_share_clock));
  }

  @Override
  public ImageView getPostToastIcon(View toast)
  {
    return (ImageView)toast.findViewById(R.id.toast_post_result_fb);
  }

  @Override
  public ImageView getLogoutToastIcon(View toast)
  {
    return (ImageView)toast.findViewById(R.id.toast_social_logout_fb);
  }

  @Override
  protected void doLogin(final Activity owner, int requestCode)
  {
    Session.openActiveSession(owner, true, new Session.StatusCallback()
    {
      // callback when session changes state
      @Override
      public void call(final Session session, SessionState state, Exception exception)
      {
        if (session.isOpened())
        {
          // make request to the /me API
          Request.executeMeRequestAsync(session, new Request.GraphUserCallback()
          {
            @Override
            public void onCompleted(GraphUser user, Response response)
            {
              FacebookRequestError error = response.getError();

              if (error == null && user != null)
              {
                Log.debug(TAG, "Facebook login succeeded " + response);
                loginListener.onLoginFinished(getRequestCode(), true);
              }
              else
              {
                Log.debug(TAG, "Facebook login failed " + error);
                loginListener.onLoginFinished(getRequestCode(), false);
              }
            }
          });
        }
      }
    });
  }

  private static final String TYPE = "Fb";
  private static final String TAG = Log.TAG + "/" + TYPE;

  private static final String PERMISSIONS = "publish_actions";
  private static final List<String> permissions = new LinkedList<String>();

  static
  {
    permissions.add(PERMISSIONS);
  }

}
